<template>
  <!-- 添加或编辑对话框 -->
  <el-dialog class="xiaobu-form-dialog" v-bind="$attrs" v-on="$listeners">
    <div v-hasPermi="['system:menu:update']" class="edit-box flex-c-e"
      v-show="baseForm.menuId && baseForm.isSystem === '0'">
      <el-button type="primary" class="edit" @click="toggleEdit">{{
        isEdit ? "取消编辑" : "编辑"
      }}</el-button>
    </div>
    <div class="el-dialog-body-child" v-closeSelect>
      <el-form class="clearfix" ref="dialogFormRef" :model="dialogForm" :rules="rules"
        :disabled="!!(!isEdit && baseForm.menuId)" label-width="120px">
        <el-form-item class="half" label="父级菜单" key="parentMenuId" prop="parentMenuId">
          <el-cascader aria-hidden="false" disabled :options="menuData" :props="props" v-model="dialogForm.parentMenuId"
            clearable placeholder="请选择父级菜单" />
        </el-form-item>
        <el-form-item class="half" label="菜单类型" key="menuType" prop="menuType">
          <el-select-dict :key="parentMenuType" :disabled="!!baseForm.menuId" v-model="dialogForm.menuType"
            dictType="MENU_TYPE" :filterDataFun="menuTypeFilterFun" @dictChange="handleClearValidate" />
        </el-form-item>

        <el-form-item class="half" :label="menuName" key="menuName" prop="menuName">
          <el-input v-model.trim="dialogForm.menuName" clearable :placeholder="`请输入${menuName}`" />
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '3'" class="half" label="按钮权限标识" key="permissionIdentification"
          prop="permissionIdentification">
          <el-select v-model="permissionIdentificationItem" value-key="label"
            @change="handlePermissionIdentificationItemChange" filterable clearable>
            <el-option v-for="(item, index) in btnList" :key="index" :label="item.label" :value="item"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1'" class="half" label="菜单链接类型" key="pathType" prop="pathType">
          <el-select-dict dictType="PATH_TYPE" v-model="dialogForm.pathType" clearable
            @dictChange="handleClearValidate" />
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1'" class="half" label="菜单访问地址" key="path" prop="path">
          <el-input v-model.trim="dialogForm.path" clearable placeholder="请输入菜单访问地址" />
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1' && dialogForm.pathType === '1'" class="half" label="菜单页面"
          key="name" prop="name">
          <el-select v-model="menuNameItem" filterable clearable @change="handleChange" value-key="name">
            <el-option v-for="(item, index) in menuNameList" :key="index" :label="item.label" :value="item"></el-option>
          </el-select>
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1' && dialogForm.pathType === '2'" class="half" label="内嵌链接地址"
          key="iframeSrc" prop="iframeSrc">
          <el-input v-model.trim="dialogForm.iframeSrc" clearable placeholder="请输入内嵌链接地址" />
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1'" class="half switch" label="是否隐藏" key="hidden" prop="hidden">
          <div class="box flex-c-s">
            <el-switch @change="dialogForm.activeMenuPath = ''" v-model="dialogForm.hidden" active-value="1"
              inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置为隐藏表示不在侧边菜单栏上显示！" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '1' && dialogForm.hidden === '1'" class="half" label="激活菜单"
          key="activeMenuPath" prop="activeMenuPath">
          <div class="box flex-c-s">
            <el-select v-model="dialogForm.activeMenuPath" placeholder="请选择激活菜单">
              <el-option v-for="(item, index) in activeMenuPathList" :key="index" :label="item.menuName"
                :value="item.path"></el-option>
            </el-select>
            <el-tooltip class="item" effect="dark" content="激活菜单即当打开此菜单页面后，左侧菜单将激活对应的菜单。" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item class="half order" label="排序" key="order" prop="order">
          <el-input-number v-model="dialogForm.order" :min="1" :step="1"></el-input-number>
        </el-form-item>

        <el-form-item class="half switch" v-if="dialogForm.menuType === '1' && dialogForm.pathType !== '3'" label="是否缓存"
          key="cache" prop="cache">
          <div class="box flex-c-s">
            <el-switch v-model="dialogForm.cache" active-value="1" inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置页面是否缓存，缓存则切换页面后切回来时页面保持离开前的状态！" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item label="是否固定" v-if="dialogForm.menuType === '1' && dialogForm.pathType !== '3'" class="half switch"
          key="affix" prop="affix">
          <div class="box flex-c-s">
            <el-switch v-model="dialogForm.affix" active-value="1" inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置是否要在标签栏上固定展示，不可关闭！" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item label="是否展示页尾" v-if="dialogForm.menuType === '1' && dialogForm.pathType !== '3'"
          class="half switch" key="showFooter" prop="showFooter">
          <div class="box flex-c-s">
            <el-switch v-model="dialogForm.showFooter" active-value="1" inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置是否要在页面的尾部展示系统页尾信息！" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item label="是否保持显示" v-if="dialogForm.menuType === '2'" class="half switch" key="alwaysShow"
          prop="alwaysShow">
          <div class="box flex-c-s">
            <el-switch v-model="dialogForm.alwaysShow" active-value="1" inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置是否在侧边菜单栏保持显示，否则当仅有一个菜单页面时不显示。" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item label=" " v-if="dialogForm.menuType !== '3' && dialogForm.pathType !== '3'" class="half switch"
          key="breadcrumb" prop="breadcrumb">
          <div class="content-label five required">是否在面包屑上展示</div>
          <div class="box flex-c-s">
            <el-switch v-model="dialogForm.breadcrumb" active-value="1" inactive-value="0"></el-switch>
            <el-tooltip class="item" effect="dark" content="设置是否在面包屑上展示！" placement="top">
              <i class="tips-icon el-icon-question"></i>
            </el-tooltip>
          </div>
        </el-form-item>

        <el-form-item v-if="dialogForm.menuType === '2'" class="all" label="菜单图标" key="iconList" prop="iconList">
          <xiaobu-upload-img :disabled="!!(!isEdit && baseForm.menuId)" accept=".svg" acceptTips="请上传svg格式的图片"
            @imgChange="handleImgChange" :max="1" :imgList="dialogForm.iconList"></xiaobu-upload-img>
          <div class="tips-box" v-show="(isEdit || !baseForm.menuId)">
            <el-tag type="warning">请上传svg格式的图片</el-tag>
          </div>
        </el-form-item>
        <el-form-item class="all" label="备注" key="remark" prop="remark">
          <el-input type="textarea" v-model="dialogForm.remark" :autosize="{ minRows: 5, maxRows: 8 }" clearable
            placeholder="请输入备注" />
        </el-form-item>
      </el-form>
    </div>
    <div slot="footer" class="dialog-footer">
      <template>
        <el-button @click="$emit('close')">{{
          !baseForm.menuId || isEdit ? "取 消" : "关 闭"
        }}</el-button>
        <el-button type="primary" @click="submitForm" v-show="!baseForm.menuId || isEdit">确 定</el-button>
      </template>
    </div>
  </el-dialog>
</template>
<script>
import { menuApi, commonApi } from "@/api"
import { urlReg, pathReg } from "@/utils/check-reg.js"
import { getDictConfigByKey } from "vue2-element-dict"
import { menuNameList, btnList } from "@/assets/menu/index.js"
import XiaobuUploadImg from "@/components/upload-img/index.vue"
export default {
  name: "MenuDialog",
  components: {
    XiaobuUploadImg
  },
  props: {
    // 新增隐藏菜单时传递
    activeMenuPathList: {
      type: Array,
      default: () => {
        return []
      }
    },
    // 菜单数据
    menuData: {
      type: Array,
      default: () => {
        return []
      }
    },
    props: {
      type: Object,
      default: () => {
        return {}
      }
    },
    parentMenuType: {
      type: String,
      default: ""
    },
    // 是否是编辑
    isUpdate: {
      type: Boolean,
      default: false
    },
    // 配置数据
    baseForm: {
      type: Object,
      default: () => {
        return {}
      }
    }
  },
  data() {
    /** 检查菜单名称是否已存在 */
    const checkMenuName = (rule, value, callback) => {
      menuApi
        .judgeMenuNameExist({ menuName: value, menuId: this.dialogForm.menuId })
        .then((data) => {
          if (data.validateResult) {
            callback()
          } else {
            callback(data.msg)
          }
        })
    }

    const checkPath = (rule, value, callback) => {
      // 菜单类型 且为 跳转外部链接的形式
      if (this.dialogForm.menuType === "1" && this.dialogForm.pathType === "3") {
        if (!value) {
          callback("请输入跳转地址")
          return
        }
        if (!urlReg.test(value)) {
          callback("请输入正确的跳转地址")
          return
        }
      } else {
        if (!value) {
          callback("请输入菜单访问地址")
          return
        }
        if (!pathReg.test(value)) {
          callback("请输入正确的菜单访问地址，如/xiaobu-admin/menu-manage")
          return
        }
      }
      menuApi
        .judgePathExist({ path: value, menuId: this.dialogForm.menuId })
        .then((data) => {
          if (data.validateResult) {
            callback()
          } else {
            callback(data.msg)
          }
        })
    }
    return {
      btnList,
      menuNameList: menuNameList,
      permissionIdentificationItem: "", // 按钮权限标识对象
      menuNameItem: "", // 选中的菜单页面权
      isEdit: false, // 是否是在编辑
      dialogForm: {}, // 弹框表单
      // 表单校验
      rules: {
        parentMenuId: [
          { required: true, message: "请选择父级菜单", trigger: "change" }
        ],
        menuName: [
          { required: true, message: "请输入菜单名称", trigger: ["blur"] },
          { validator: checkMenuName, trigger: ["blur"] }
        ],
        menuType: [
          { required: true, message: "请选择菜单类型", trigger: "change" }
        ],
        path: [
          { required: true, message: "请输入菜单访问地址", trigger: ["blur"] },
          { validator: checkPath, trigger: ["blur"] }
        ],
        order: [{ required: true, message: "请输入排序", trigger: "blur" }],
        activeMenuPath: [
          { required: true, message: "请选择激活菜单", trigger: "change" }
        ],
        permissionIdentification: [
          { required: true, message: "请选择按钮权限标识", trigger: "change" }
        ],
        name: [{ required: true, message: "请选择页面", trigger: "change" }],
        iframeSrc: [
          {
            required: true,
            message: "请输入链接url",
            trigger: ["blur"]
          },
          {
            pattern: urlReg,
            message: "请输入正确的链接url",
            trigger: ["blur"]
          }
        ],
        iconList: [
          { required: true, message: "请上传菜单图表", trigger: "change" }
        ]
      }
    }
  },
  computed: {
    menuName() {
      return this.dialogForm.menuType === "1"
        ? "菜单名称"
        : this.dialogForm.menuType === "2"
          ? "目录名称"
          : "按钮名称"
    }
  },
  watch: {
    isUpdate(val) {
      this.isEdit = val
    },
    // 监听baseForm变化 拷贝baseForm
    baseForm: {
      handler: function(val) {
        this.renderPageData(val)

      },
      immediate: true,
      deep: true
    }
  },
  methods: {
    // 重新渲染页面数据
    renderPageData(val) {
      this.dialogForm = JSON.parse(JSON.stringify(val))
      this.dialogForm.deleteFiles = ""

      if (this.dialogForm.name) {
        // 渲染页面
        const target = this.menuNameList.find((item) => {
          return item.name === this.dialogForm.name
        })
        this.menuNameItem = target
      }

      //  渲染按钮权限标识
      if (this.dialogForm.permissionIdentification && this.dialogForm.menuType === "3") {
        // 渲染页面
        const target = this.btnList.find((item) => {
          return item.value === this.dialogForm.permissionIdentification
        })
        this.permissionIdentificationItem = target
      }

      if (this.dialogForm.icon) {
        this.dialogForm.iconList = [{
          name: "菜单图标",
          url: this.dialogForm.icon
        }]
      } else {
        this.dialogForm.iconList = []
      }
    },
    // 编辑或取消编辑
    toggleEdit() {
      if (!this.isEdit) {
        this.isEdit = true
        return
      }
      this.isEdit = false
      this.renderPageData(this.baseForm)
    },
    // 图片改变事件
    handleImgChange(iconList) {
      this.dialogForm.iconList = iconList
      this.$refs.dialogFormRef.validateField("iconList")
    },
    // 重置表单
    resetForm() {
      this.isEdit = false
      this.menuNameItem = ""
      this.permissionIdentificationItem = ""
      this.$nextTick(() => {
        this.$refs.dialogFormRef.clearValidate()
      })
    },
    /** 提交按钮 */
    submitForm() {
      this.$refs["dialogFormRef"].validate(async valid => {
        if (valid) {
          if (this.dialogForm.menuType === "2") { // 目录类型 且 无上传新
            const formData = new FormData()
            const targetItem = this.dialogForm.iconList[0]
            if (targetItem?.raw) {
              formData.append("file", targetItem.raw, targetItem.name)
              formData.append("fileFolder", "svg") // 上传的文件夹
              const data = await commonApi.upload(formData)
              if (!data) { return }
              // 多传删除的图片地址 字符串格式 英文逗号隔开 
              this.dialogForm.deleteFiles = this.dialogForm.icon
              this.dialogForm.icon = data.url
            }
          }
          //更新
          if (this.dialogForm.menuId) {
            // 不是普通路径菜单 数据表权限标识置空
            if (this.dialogForm.menuType !== "1" || this.dialogForm.pathType !== "1") {
              this.dialogForm.recycleBinIdentification = ""
            }
            // 不是普通路径菜单 且不是按钮类型 权限标识 置空
            if (!((this.dialogForm.menuType === "1" && this.dialogForm.pathType === "1") || this.dialogForm.menuType === "3")) {
              this.dialogForm.permissionIdentification = ""
            }
            menuApi.updateItem(this.dialogForm).then((data) => {
              this.$modal.msgSuccess("编辑菜单成功")
              this.$emit("close")
              this.$emit("successs")
            })
          } else {
            // 不是普通路径菜单 数据表权限标识置空
            if (this.dialogForm.menuType !== "1" || this.dialogForm.pathType !== "1") {
              this.dialogForm.recycleBinIdentification = ""
            }
            // 不是普通路径菜单 且不是按钮类型 权限标识 置空
            if (!((this.dialogForm.menuType === "1" && this.dialogForm.pathType === "1") || this.dialogForm.menuType === "3")) {
              this.dialogForm.permissionIdentification = ""
            }
            //新增
            menuApi.createItem(this.dialogForm).then((data) => {
              this.$modal.msgSuccess("新增菜单成功")
              this.$emit("close")
              this.$emit("successs")
            })
          }
        }
      })
    },
    // 按钮权限标识改变事件
    handlePermissionIdentificationItemChange(val) {
      if (val) {
        this.dialogForm.permissionIdentification = val.value
      } else {
        this.dialogForm.permissionIdentification = ""
      }
    },
    // 清除校验
    handleClearValidate() {
      this.$refs.dialogFormRef.clearValidate()
    },

    // 菜单页面改变事件
    handleChange(val) {
      if (!val) {
        this.dialogForm.name = ""
        this.dialogForm.permissionIdentification = ""
        this.dialogForm.recycleBinIdentification = ""
        return
      }
      this.dialogForm.name = val.name
      this.dialogForm.permissionIdentification = val.permissionIdentification
      this.dialogForm.recycleBinIdentification = val.recycleBinIdentification || ""
    },

    // 过滤可选的 菜单类型
    menuTypeFilterFun(list) {
      if (!this.parentMenuType) {
        return list
      }
      const format = getDictConfigByKey("format")
      if (this.parentMenuType === "2") {
        // 目录类型 过滤掉按钮菜单类型
        return list.filter((item) => {
          return item[format.value] !== "3"
        })
      }

      // 菜单类型 只可添加 按钮
      return list.filter((item) => {
        return item[format.value] === "3"
      })
    }
  }
}
</script>
